home *** CD-ROM | disk | FTP | other *** search
/ Collection of Tools & Utilities / Collection of Tools and Utilities.iso / graphic / jpegsrc4.zip / JRDJFIF.C < prev    next >
C/C++ Source or Header  |  1992-12-02  |  24KB  |  843 lines

  1. /*
  2.  * jrdjfif.c
  3.  *
  4.  * Copyright (C) 1991, 1992, Thomas G. Lane.
  5.  * This file is part of the Independent JPEG Group's software.
  6.  * For conditions of distribution and use, see the accompanying README file.
  7.  *
  8.  * This file contains routines to decode standard JPEG file headers/markers.
  9.  * This code will handle "raw JPEG" and JFIF-convention JPEG files.
  10.  *
  11.  * You can also use this module to decode a raw-JPEG or JFIF-standard data
  12.  * stream that is embedded within a larger file.  To do that, you must
  13.  * position the file to the JPEG SOI marker (0xFF/0xD8) that begins the
  14.  * data sequence to be decoded.  If nothing better is possible, you can scan
  15.  * the file until you see the SOI marker, then use JUNGETC to push it back.
  16.  *
  17.  * This module relies on the JGETC macro and the read_jpeg_data method (which
  18.  * is provided by the user interface) to read from the JPEG data stream.
  19.  * Therefore, this module is not dependent on any particular assumption about
  20.  * the data source; it need not be a stdio stream at all.  (This fact does
  21.  * NOT carry over to more complex JPEG file formats such as JPEG-in-TIFF;
  22.  * those format control modules may well need to assume stdio input.)
  23.  *
  24.  * These routines are invoked via the methods read_file_header,
  25.  * read_scan_header, read_jpeg_data, read_scan_trailer, and read_file_trailer.
  26.  */
  27.  
  28. #include "jinclude.h"
  29.  
  30. #ifdef JFIF_SUPPORTED
  31.  
  32.  
  33. typedef enum {            /* JPEG marker codes */
  34.   M_SOF0  = 0xc0,
  35.   M_SOF1  = 0xc1,
  36.   M_SOF2  = 0xc2,
  37.   M_SOF3  = 0xc3,
  38.   
  39.   M_SOF5  = 0xc5,
  40.   M_SOF6  = 0xc6,
  41.   M_SOF7  = 0xc7,
  42.   
  43.   M_JPG   = 0xc8,
  44.   M_SOF9  = 0xc9,
  45.   M_SOF10 = 0xca,
  46.   M_SOF11 = 0xcb,
  47.   
  48.   M_SOF13 = 0xcd,
  49.   M_SOF14 = 0xce,
  50.   M_SOF15 = 0xcf,
  51.   
  52.   M_DHT   = 0xc4,
  53.   
  54.   M_DAC   = 0xcc,
  55.   
  56.   M_RST0  = 0xd0,
  57.   M_RST1  = 0xd1,
  58.   M_RST2  = 0xd2,
  59.   M_RST3  = 0xd3,
  60.   M_RST4  = 0xd4,
  61.   M_RST5  = 0xd5,
  62.   M_RST6  = 0xd6,
  63.   M_RST7  = 0xd7,
  64.   
  65.   M_SOI   = 0xd8,
  66.   M_EOI   = 0xd9,
  67.   M_SOS   = 0xda,
  68.   M_DQT   = 0xdb,
  69.   M_DNL   = 0xdc,
  70.   M_DRI   = 0xdd,
  71.   M_DHP   = 0xde,
  72.   M_EXP   = 0xdf,
  73.   
  74.   M_APP0  = 0xe0,
  75.   M_APP15 = 0xef,
  76.   
  77.   M_JPG0  = 0xf0,
  78.   M_JPG13 = 0xfd,
  79.   M_COM   = 0xfe,
  80.   
  81.   M_TEM   = 0x01,
  82.   
  83.   M_ERROR = 0x100
  84. } JPEG_MARKER;
  85.  
  86.  
  87. /*
  88.  * Reload the input buffer after it's been emptied, and return the next byte.
  89.  * This is exported for direct use by the entropy decoder.
  90.  * See the JGETC macro for calling conditions.  Note in particular that
  91.  * read_jpeg_data may NOT return EOF.  If no more data is available, it must
  92.  * exit via ERREXIT, or perhaps synthesize fake data (such as an RST marker).
  93.  * For error recovery purposes, synthesizing an EOI marker is probably best.
  94.  *
  95.  * For this header control module, read_jpeg_data is supplied by the
  96.  * user interface.  However, header formats that require random access
  97.  * to the input file would need to supply their own code.  This code is
  98.  * left here to indicate what is required.
  99.  */
  100.  
  101. #if 0                /* not needed in this module */
  102.  
  103. METHODDEF int
  104. read_jpeg_data (decompress_info_ptr cinfo)
  105. {
  106.   cinfo->next_input_byte = cinfo->input_buffer + MIN_UNGET;
  107.  
  108.   cinfo->bytes_in_buffer = (int) JFREAD(cinfo->input_file,
  109.                     cinfo->next_input_byte,
  110.                     JPEG_BUF_SIZE);
  111.   
  112.   if (cinfo->bytes_in_buffer <= 0) {
  113.     WARNMS(cinfo->emethods, "Premature EOF in JPEG file");
  114.     cinfo->next_input_byte[0] = (char) 0xFF;
  115.     cinfo->next_input_byte[1] = (char) M_EOI;
  116.     cinfo->bytes_in_buffer = 2;
  117.   }
  118.  
  119.   return JGETC(cinfo);
  120. }
  121.  
  122. #endif
  123.  
  124.  
  125. /*
  126.  * Routines to parse JPEG markers & save away the useful info.
  127.  */
  128.  
  129.  
  130. LOCAL INT32
  131. get_2bytes (decompress_info_ptr cinfo)
  132. /* Get a 2-byte unsigned integer (e.g., a marker parameter length field) */
  133. {
  134.   INT32 a;
  135.   
  136.   a = JGETC(cinfo);
  137.   return (a << 8) + JGETC(cinfo);
  138. }
  139.  
  140.  
  141. LOCAL void
  142. skip_variable (decompress_info_ptr cinfo, int code)
  143. /* Skip over an unknown or uninteresting variable-length marker */
  144. {
  145.   INT32 length;
  146.   
  147.   length = get_2bytes(cinfo);
  148.   
  149.   TRACEMS2(cinfo->emethods, 1,
  150.        "Skipping marker 0x%02x, length %u", code, (int) length);
  151.   
  152.   for (length -= 2; length > 0; length--)
  153.     (void) JGETC(cinfo);
  154. }
  155.  
  156.  
  157. LOCAL void
  158. get_dht (decompress_info_ptr cinfo)
  159. /* Process a DHT marker */
  160. {
  161.   INT32 length;
  162.   UINT8 bits[17];
  163.   UINT8 huffval[256];
  164.   int i, index, count;
  165.   HUFF_TBL **htblptr;
  166.   
  167.   length = get_2bytes(cinfo)-2;
  168.   
  169.   while (length > 0) {
  170.     index = JGETC(cinfo);
  171.  
  172.     TRACEMS1(cinfo->emethods, 1, "Define Huffman Table 0x%02x", index);
  173.       
  174.     bits[0] = 0;
  175.     count = 0;
  176.     for (i = 1; i <= 16; i++) {
  177.       bits[i] = (UINT8) JGETC(cinfo);
  178.       count += bits[i];
  179.     }
  180.  
  181.     TRACEMS8(cinfo->emethods, 2, "        %3d %3d %3d %3d %3d %3d %3d %3d",
  182.          bits[1], bits[2], bits[3], bits[4],
  183.          bits[5], bits[6], bits[7], bits[8]);
  184.     TRACEMS8(cinfo->emethods, 2, "        %3d %3d %3d %3d %3d %3d %3d %3d",
  185.          bits[9], bits[10], bits[11], bits[12],
  186.          bits[13], bits[14], bits[15], bits[16]);
  187.  
  188.     if (count > 256)
  189.       ERREXIT(cinfo->emethods, "Bogus DHT counts");
  190.  
  191.     for (i = 0; i < count; i++)
  192.       huffval[i] = (UINT8) JGETC(cinfo);
  193.  
  194.     length -= 1 + 16 + count;
  195.  
  196.     if (index & 0x10) {        /* AC table definition */
  197.       index -= 0x10;
  198.       htblptr = &cinfo->ac_huff_tbl_ptrs[index];
  199.     } else {            /* DC table definition */
  200.       htblptr = &cinfo->dc_huff_tbl_ptrs[index];
  201.     }
  202.  
  203.     if (index < 0 || index >= NUM_HUFF_TBLS)
  204.       ERREXIT1(cinfo->emethods, "Bogus DHT index %d", index);
  205.  
  206.     if (*htblptr == NULL)
  207.       *htblptr = (HUFF_TBL *) (*cinfo->emethods->alloc_small) (SIZEOF(HUFF_TBL));
  208.   
  209.     MEMCOPY((*htblptr)->bits, bits, SIZEOF((*htblptr)->bits));
  210.     MEMCOPY((*htblptr)->huffval, huffval, SIZEOF((*htblptr)->huffval));
  211.     }
  212. }
  213.  
  214.  
  215. LOCAL void
  216. get_dac (decompress_info_ptr cinfo)
  217. /* Process a DAC marker */
  218. {
  219.   INT32 length;
  220.   int index, val;
  221.  
  222.   length = get_2bytes(cinfo)-2;
  223.   
  224.   while (length > 0) {
  225.     index = JGETC(cinfo);
  226.     val = JGETC(cinfo);
  227.  
  228.     TRACEMS2(cinfo->emethods, 1,
  229.          "Define Arithmetic Table 0x%02x: 0x%02x", index, val);
  230.  
  231.     if (index < 0 || index >= (2*NUM_ARITH_TBLS))
  232.       ERREXIT1(cinfo->emethods, "Bogus DAC index %d", index);
  233.  
  234.     if (index >= NUM_ARITH_TBLS) { /* define AC table */
  235.       cinfo->arith_ac_K[index-NUM_ARITH_TBLS] = (UINT8) val;
  236.     } else {            /* define DC table */
  237.       cinfo->arith_dc_L[index] = (UINT8) (val & 0x0F);
  238.       cinfo->arith_dc_U[index] = (UINT8) (val >> 4);
  239.       if (cinfo->arith_dc_L[index] > cinfo->arith_dc_U[index])
  240.     ERREXIT1(cinfo->emethods, "Bogus DAC value 0x%x", val);
  241.     }
  242.  
  243.     length -= 2;
  244.   }
  245. }
  246.  
  247.  
  248. LOCAL void
  249. get_dqt (decompress_info_ptr cinfo)
  250. /* Process a DQT marker */
  251. {
  252.   INT32 length;
  253.   int n, i, prec;
  254.   UINT16 tmp;
  255.   QUANT_TBL_PTR quant_ptr;
  256.   
  257.   length = get_2bytes(cinfo) - 2;
  258.   
  259.   while (length > 0) {
  260.     n = JGETC(cinfo);
  261.     prec = n >> 4;
  262.     n &= 0x0F;
  263.  
  264.     TRACEMS2(cinfo->emethods, 1,
  265.          "Define Quantization Table %d  precision %d", n, prec);
  266.  
  267.     if (n >= NUM_QUANT_TBLS)
  268.       ERREXIT1(cinfo->emethods, "Bogus table number %d", n);
  269.       
  270.     if (cinfo->quant_tbl_ptrs[n] == NULL)
  271.       cinfo->quant_tbl_ptrs[n] = (QUANT_TBL_PTR)
  272.     (*cinfo->emethods->alloc_small) (SIZEOF(QUANT_TBL));
  273.     quant_ptr = cinfo->quant_tbl_ptrs[n];
  274.  
  275.     for (i = 0; i < DCTSIZE2; i++) {
  276.       tmp = JGETC(cinfo);
  277.       if (prec)
  278.     tmp = (tmp<<8) + JGETC(cinfo);
  279.       quant_ptr[i] = tmp;
  280.     }
  281.  
  282.     for (i = 0; i < DCTSIZE2; i += 8) {
  283.       TRACEMS8(cinfo->emethods, 2, "        %4u %4u %4u %4u %4u %4u %4u %4u",
  284.            quant_ptr[i  ], quant_ptr[i+1], quant_ptr[i+2], quant_ptr[i+3],
  285.            quant_ptr[i+4], quant_ptr[i+5], quant_ptr[i+6], quant_ptr[i+7]);
  286.     }
  287.  
  288.     length -= DCTSIZE2+1;
  289.     if (prec) length -= DCTSIZE2;
  290.   }
  291. }
  292.  
  293.  
  294. LOCAL void
  295. get_dri (decompress_info_ptr cinfo)
  296. /* Process a DRI marker */
  297. {
  298.   if (get_2bytes(cinfo) != 4)
  299.     ERREXIT(cinfo->emethods, "Bogus length in DRI");
  300.  
  301.   cinfo->restart_interval = (UINT16) get_2bytes(cinfo);
  302.  
  303.   TRACEMS1(cinfo->emethods, 1,
  304.        "Define Restart Interval %u", cinfo->restart_interval);
  305. }
  306.